package org.jeecg.modules.wms.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.config.TenantContext;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.wms.util.QRCodeUtil;
import org.jeecg.modules.wms.entity.WmsWarehouse;
import org.jeecg.modules.wms.entity.WmsWarehouseLocation;
import org.jeecg.modules.wms.mapper.WmsWarehouseLocationMapper;
import org.jeecg.modules.wms.service.IWmsWarehouseLocationService;
import org.jeecg.modules.wms.service.IWmsWarehouseService;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.params.ExcelExportEntity;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import java.util.stream.Collectors;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import javax.sql.DataSource;

/**
 * 库位信息服务实现类
 */
@Slf4j
@Service
public class WmsWarehouseLocationServiceImpl extends ServiceImpl<WmsWarehouseLocationMapper, WmsWarehouseLocation> implements IWmsWarehouseLocationService {

    @Autowired
    private IWmsWarehouseService wmsWarehouseService;

    @Autowired
    private DataSource dataSource;
    
    @Value("${jeecg.path.upload}")
    private String uploadPath;

    @Override
    public List<WmsWarehouseLocation> queryLocationListByWarehouseId(String warehouseId) {
        LambdaQueryWrapper<WmsWarehouseLocation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(WmsWarehouseLocation::getWarehouseId, warehouseId);
        List<WmsWarehouseLocation> list = list(queryWrapper);
        
        // 填充仓库名称
        if (list != null && !list.isEmpty() && StringUtils.isNotBlank(warehouseId)) {
            WmsWarehouse warehouse = wmsWarehouseService.getById(warehouseId);
            if (warehouse != null) {
                String warehouseName = warehouse.getWarehouseName();
                for (WmsWarehouseLocation location : list) {
                    location.setWarehouseName(warehouseName);
                }
            }
        }
        
        return list;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveLocation(WmsWarehouseLocation wmsWarehouseLocation) {
        // 设置租户ID
        String tenantId = TenantContext.getTenant();
        if (StringUtils.isNotBlank(tenantId)) {
            wmsWarehouseLocation.setTenantId(tenantId);
        }
        
        // 获取仓库信息
        String warehouseId = wmsWarehouseLocation.getWarehouseId();
        if (StringUtils.isBlank(warehouseId)) {
            throw new JeecgBootException("仓库ID不能为空");
        }
        
        WmsWarehouse warehouse = wmsWarehouseService.getById(warehouseId);
        if (warehouse == null) {
            throw new JeecgBootException("仓库不存在");
        }
        
        // 生成库位编号：仓库编号-自增数
        if (StringUtils.isBlank(wmsWarehouseLocation.getLocationCode())) {
            String warehouseCode = warehouse.getWarehouseCode();
            
            // 查询当前仓库下最大的库位编号
            LambdaQueryWrapper<WmsWarehouseLocation> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(WmsWarehouseLocation::getWarehouseId, warehouseId)
                      .likeRight(WmsWarehouseLocation::getLocationCode, warehouseCode + "-")
                      .orderByDesc(WmsWarehouseLocation::getLocationCode);
            if (StringUtils.isNotBlank(tenantId)) {
                queryWrapper.eq(WmsWarehouseLocation::getTenantId, tenantId);
            }
            
            List<WmsWarehouseLocation> locationList = list(queryWrapper);
            
            int nextNum = 1;
            if (locationList != null && !locationList.isEmpty()) {
                // 从库位编号中提取最大的序号
                String maxLocationCode = locationList.get(0).getLocationCode();
                String[] parts = maxLocationCode.split("-");
                if (parts.length > 1) {
                    try {
                        nextNum = Integer.parseInt(parts[1]) + 1;
                    } catch (NumberFormatException e) {
                        nextNum = 1;
                    }
                }
            }
            
            // 生成新的库位编号
            String locationCode = warehouseCode + "-" + String.format("%04d", nextNum);
            wmsWarehouseLocation.setLocationCode(locationCode);
        } else {
            // 检查库位编号是否已存在（在当前租户下唯一）
            LambdaQueryWrapper<WmsWarehouseLocation> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(WmsWarehouseLocation::getLocationCode, wmsWarehouseLocation.getLocationCode());
            if (StringUtils.isNotBlank(tenantId)) {
                queryWrapper.eq(WmsWarehouseLocation::getTenantId, tenantId);
            }
            
            Long count = count(queryWrapper);
            if (count > 0) {
                throw new JeecgBootException("库位编号已存在，请更换其他编号");
            }
            
            // 验证库位编号格式是否符合要求：仓库编号-自增数
            String locationCode = wmsWarehouseLocation.getLocationCode();
            String warehouseCode = warehouse.getWarehouseCode();
            if (!locationCode.startsWith(warehouseCode + "-")) {
                throw new JeecgBootException("库位编号格式不正确，应为：" + warehouseCode + "-XXXX");
            }
        }
        
        // 设置默认状态为空闲
        if (StringUtils.isBlank(wmsWarehouseLocation.getStatus())) {
            wmsWarehouseLocation.setStatus("1");
        }
        
        // 保存库位信息
        boolean result = save(wmsWarehouseLocation);
        
        if (result) {
            // 更新仓库库位总数
            updateWarehouseLocationCount(wmsWarehouseLocation.getWarehouseId());
            
            // 自动生成库位二维码
            try {
                String locationCode = wmsWarehouseLocation.getLocationCode();
                String locationName = wmsWarehouseLocation.getLocationName();
                if (StringUtils.isNotBlank(locationCode)) {
                    String fileName = wmsWarehouseLocation.getTenantId() + "_" + locationCode + ".png";
                    String relativePath = "qrcode/location/" + fileName;
                    String realPath = uploadPath + File.separator + relativePath;
                    
                    // 确保目录存在
                    File file = new File(realPath);
                    if (!file.getParentFile().exists()) {
                        file.getParentFile().mkdirs();
                    }
                    
                    // 生成带信息的二维码
                    QRCodeUtil.encodeWithInfo(
                        locationCode,
                        realPath,
                        warehouse.getWarehouseCode(),
                        locationCode,
                        locationName
                    );
                    
                    // 更新库位二维码路径
                    wmsWarehouseLocation.setLocationQrcode(relativePath);
                    updateById(wmsWarehouseLocation);
                }
            } catch (Exception e) {
                log.error("自动生成库位二维码失败", e);
                // 不抛出异常，不影响库位保存
            }
        }
        
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateLocation(WmsWarehouseLocation wmsWarehouseLocation) {
        // 检查库位编号是否已存在（在当前租户下唯一，排除自身）
        if (StringUtils.isNotBlank(wmsWarehouseLocation.getLocationCode())) {
            String tenantId = TenantContext.getTenant();
            
            LambdaQueryWrapper<WmsWarehouseLocation> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(WmsWarehouseLocation::getLocationCode, wmsWarehouseLocation.getLocationCode())
                      .ne(WmsWarehouseLocation::getId, wmsWarehouseLocation.getId());
            if (StringUtils.isNotBlank(tenantId)) {
                queryWrapper.eq(WmsWarehouseLocation::getTenantId, tenantId);
            }
            
            Long count = count(queryWrapper);
            if (count > 0) {
                throw new JeecgBootException("库位编号已存在，请更换其他编号");
            }
            
//            // 验证库位编号格式是否符合要求：仓库编号-自增数
//            String warehouseId = wmsWarehouseLocation.getWarehouseId();
//            if (StringUtils.isNotBlank(warehouseId)) {
//                WmsWarehouse warehouse = wmsWarehouseService.getById(warehouseId);
//                if (warehouse != null) {
//                    String locationCode = wmsWarehouseLocation.getLocationCode();
//                    String warehouseCode = warehouse.getWarehouseCode();
//                    if (!locationCode.startsWith(warehouseCode + "-")) {
//                        throw new JeecgBootException("库位编号格式不正确，应为：" + warehouseCode + "-XXXX");
//                    }
//                }
//            }
        }
        
        // 检查库位码是否已生成，如果没有则自动生成
        if (StringUtils.isBlank(wmsWarehouseLocation.getLocationQrcode()) || wmsWarehouseLocation.isForceUpdateQrcode()) {
            try {
                String locationCode = wmsWarehouseLocation.getLocationCode();
                String locationName = wmsWarehouseLocation.getLocationName();
                String warehouseId = wmsWarehouseLocation.getWarehouseId();
                
                if (StringUtils.isNotBlank(locationCode) && StringUtils.isNotBlank(warehouseId)) {
                    // 获取仓库信息
                    WmsWarehouse warehouse = wmsWarehouseService.getById(warehouseId);
                    if (warehouse != null) {
                        String fileName = wmsWarehouseLocation.getTenantId() + "_" +locationCode + ".png";
                        String relativePath = "qrcode/location/" + fileName;
                        String realPath = uploadPath + File.separator + relativePath;
                        
                        // 确保目录存在
                        File file = new File(realPath);
                        if (!file.getParentFile().exists()) {
                            file.getParentFile().mkdirs();
                        }
                        
                        // 生成带信息的二维码
                        QRCodeUtil.encodeWithInfo(
                            locationCode,
                            realPath,
                            warehouse.getWarehouseCode(),
                            locationCode,
                            locationName
                        );
                        
                        // 设置库位二维码路径
                        wmsWarehouseLocation.setLocationQrcode(relativePath);
                    }
                }
            } catch (Exception e) {
                log.error("自动生成库位二维码失败", e);
                // 不抛出异常，不影响库位更新
            }
        }

        if(oConvertUtils.isNotEmpty(wmsWarehouseLocation.getMaterialCodeList())){
            wmsWarehouseLocation.setMaterialCodeList(wmsWarehouseLocation.getMaterialCodeList().replaceAll("，", ","));
        }
        
        return updateById(wmsWarehouseLocation);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteLocation(String id) {
        WmsWarehouseLocation location = getById(id);
        if (location == null) {
            return false;
        }
        
        // 先删除二维码文件（如果存在）
        if (StringUtils.isNotBlank(location.getLocationQrcode())) {
            try {
                String qrcodePath = uploadPath + File.separator + location.getLocationQrcode();
                File qrcodeFile = new File(qrcodePath);
                if (qrcodeFile.exists() && qrcodeFile.isFile()) {
                    qrcodeFile.delete();
                }
            } catch (Exception e) {
                log.error("删除库位二维码文件时发生错误", e);
                // 不抛出异常，不影响库位删除
            }
        }
        
        boolean result = removeById(id);
        if (result) {
            // 更新仓库库位总数
            updateWarehouseLocationCount(location.getWarehouseId());
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchDeleteLocation(String ids) {
        if (StringUtils.isBlank(ids)) {
            return false;
        }
        String[] idArray = ids.split(",");
        boolean allSuccess = true;
        for (String id : idArray) {
            boolean success = deleteLocation(id);
            if (!success) {
                allSuccess = false;
            }
        }
        return allSuccess;
    }

    @Override
    public String generateLocationQrcode(String id) {
        WmsWarehouseLocation location = getById(id);
        if (location == null) {
            throw new JeecgBootException("库位不存在！");
        }
        
        if (StringUtils.isBlank(location.getLocationCode())) {
            throw new JeecgBootException("库位编码不能为空，无法生成二维码");
        }
        
        // 获取仓库信息，用于在二维码下方添加仓库编号
        WmsWarehouse warehouse = wmsWarehouseService.getById(location.getWarehouseId());
        if (warehouse == null) {
            throw new JeecgBootException("仓库不存在，无法生成二维码");
        }
        
        String qrcodeContent = location.getLocationCode();
        String fileName = location.getLocationCode() + ".png";
        String relativePath = "qrcode/location/" + fileName;
        String realPath = uploadPath + File.separator + relativePath;
        
        try {
            // 确保目录存在
            File file = new File(realPath);
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }
            
            // 生成二维码，包含仓库编号、库位编号和库位名称等信息
            QRCodeUtil.encodeWithInfo(
                qrcodeContent,
                realPath,
                warehouse.getWarehouseCode(),  // 仓库编号
                location.getLocationCode(),    // 库位编号
                location.getLocationName()     // 库位名称
            );
            
            // 更新库位二维码路径
            location.setLocationQrcode(relativePath);
            updateById(location);
            
            return relativePath;
        } catch (Exception e) {
            log.error("生成库位二维码失败", e);
            throw new JeecgBootException("生成库位二维码失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchGenerateLocationQrcode(String warehouseId) {
        List<WmsWarehouseLocation> locationList = queryLocationListByWarehouseId(warehouseId);
        if (locationList == null || locationList.isEmpty()) {
            throw new JeecgBootException("该仓库下没有库位！");
        }
        
        for (WmsWarehouseLocation location : locationList) {
            generateLocationQrcode(location.getId());
        }
        return true;
    }

    /**
     * 更新仓库库位总数
     *
     * @param warehouseId 仓库ID
     */
    private void updateWarehouseLocationCount(String warehouseId) {
        // 查询当前仓库下的库位数量
        LambdaQueryWrapper<WmsWarehouseLocation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(WmsWarehouseLocation::getWarehouseId, warehouseId);
        String tenantId = TenantContext.getTenant();
        if (StringUtils.isNotBlank(tenantId)) {
            queryWrapper.eq(WmsWarehouseLocation::getTenantId, tenantId);
        }
        
        Long locationCount = count(queryWrapper);
        
        // 更新仓库库位总数
        WmsWarehouse warehouse = new WmsWarehouse();
        warehouse.setId(warehouseId);
        warehouse.setLocationCount(locationCount);
        wmsWarehouseService.updateById(warehouse);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int batchGenerateLocation(String warehouseId, String codePrefix, String namePrefix, Integer startNum, Integer count, Integer numLength, String status, String remark) {
        // 参数校验
        if (warehouseId == null || "".equals(warehouseId)) {
            throw new JeecgBootException("仓库ID不能为空");
        }
        if (codePrefix == null || "".equals(codePrefix)) {
            throw new JeecgBootException("库位编号前缀不能为空");
        }
        if (namePrefix == null || "".equals(namePrefix)) {
            throw new JeecgBootException("库位名称前缀不能为空");
        }
        if (startNum == null || startNum < 1) {
            throw new JeecgBootException("起始编号必须大于0");
        }
        if (count == null || count < 1) {
            throw new JeecgBootException("生成数量必须大于0");
        }
        if (numLength == null || numLength < 1) {
            throw new JeecgBootException("编号位数必须大于0");
        }

        // 获取仓库信息
        WmsWarehouse warehouse = wmsWarehouseService.getById(warehouseId);
        if (warehouse == null) {
            throw new JeecgBootException("仓库不存在");
        }

        // 获取租户ID
        String tenantId = TenantContext.getTenant();

        // 批量生成库位
        int successCount = 0;
        for (int i = 0; i < count; i++) {
            int currentNum = startNum + i;
            // 格式化编号，如：001、002...
            String numStr = String.format("%0" + numLength + "d", currentNum);
            
            // 生成库位编号和名称
            String locationCode = codePrefix + numStr;
            String locationName = namePrefix + numStr;
            
            // 检查库位编号是否已存在
            LambdaQueryWrapper<WmsWarehouseLocation> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(WmsWarehouseLocation::getLocationCode, locationCode);
            if (StringUtils.isNotBlank(tenantId)) {
                queryWrapper.eq(WmsWarehouseLocation::getTenantId, tenantId);
            }
            
            Long existCount = count(queryWrapper);
            if (existCount > 0) {
                continue;
            }
            
            // 创建库位对象
            WmsWarehouseLocation location = new WmsWarehouseLocation();
            location.setWarehouseId(warehouseId);
            location.setLocationCode(locationCode);
            location.setLocationName(locationName);
            location.setStatus(status);
            location.setRemark(remark);
            
            // 设置租户ID
            if (StringUtils.isNotBlank(tenantId)) {
                location.setTenantId(tenantId);
            }
            
            // 保存库位信息
            boolean result = save(location);
            if (result) {
                successCount++;
                
                // 自动生成库位二维码
                try {
                    String fileName = location.getTenantId() + "_" +locationCode + ".png";
                    String relativePath = "qrcode/location/" + fileName;
                    String realPath = uploadPath + File.separator + relativePath;
                    
                    // 确保目录存在
                    File file = new File(realPath);
                    if (!file.getParentFile().exists()) {
                        file.getParentFile().mkdirs();
                    }
                    
                    // 生成带信息的二维码
                    QRCodeUtil.encodeWithInfo(
                        locationCode,
                        realPath,
                        warehouse.getWarehouseCode(),
                        locationCode,
                        locationName
                    );
                    
                    // 更新库位二维码路径
                    location.setLocationQrcode(relativePath);
                    updateById(location);
                } catch (Exception e) {
                    log.error("批量生成库位二维码失败", e);
                    // 不抛出异常，不影响后续库位生成
                }
            }
        }
        
        // 更新仓库库位总数
        if (successCount > 0) {
            updateWarehouseLocationCount(warehouseId);
        }
        
        return successCount;
    }

    @Override
    public List<WmsWarehouseLocation> queryExportList(WmsWarehouseLocation wmsWarehouseLocation, Map<String, String[]> parameterMap) {
        // 组装查询条件
        QueryWrapper<WmsWarehouseLocation> queryWrapper = QueryGenerator.initQueryWrapper(wmsWarehouseLocation, parameterMap);
        
        // 过滤选中数据
        String selections = parameterMap.get("selections") != null && parameterMap.get("selections").length > 0 ? 
                parameterMap.get("selections")[0] : null;
        if (oConvertUtils.isNotEmpty(selections)) {
            List<String> selectionList = Arrays.asList(selections.split(","));
            queryWrapper.in("id", selectionList);
        }
        
        // 获取导出数据
        List<WmsWarehouseLocation> locationList = list(queryWrapper);
        
        // 获取所有查询结果的仓库ID
        List<String> warehouseIds = locationList.stream()
                .map(WmsWarehouseLocation::getWarehouseId)
                .filter(StringUtils::isNotBlank)
                .distinct()
                .collect(Collectors.toList());
        
        if (!warehouseIds.isEmpty()) {
            // 批量查询仓库信息
            List<WmsWarehouse> warehouseList = wmsWarehouseService.listByIds(warehouseIds);
            Map<String, String> warehouseMap = warehouseList.stream()
                    .collect(Collectors.toMap(WmsWarehouse::getId, WmsWarehouse::getWarehouseName, (k1, k2) -> k1));
            
            // 填充仓库名称
            for (WmsWarehouseLocation location : locationList) {
                if (StringUtils.isNotBlank(location.getWarehouseId())) {
                    location.setWarehouseName(warehouseMap.get(location.getWarehouseId()));
                }
            }
        }
        
        return locationList;
    }
    
    @Override
    public ModelAndView exportXls(HttpServletRequest request, List<WmsWarehouseLocation> pageList, Class<WmsWarehouseLocation> clazz, String title, List<String> excludeColumns) {
        // 获取登录用户
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        
        // 创建Excel视图
        ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
        // 设置文件名
        mv.addObject(NormalExcelConstants.FILE_NAME, title);
        
        // 设置导出参数
        ExportParams exportParams = new ExportParams(title + "报表", "导出人:" + sysUser.getRealname(), title);
        exportParams.setImageBasePath(uploadPath);
        mv.addObject(NormalExcelConstants.PARAMS, exportParams);
        mv.addObject(NormalExcelConstants.CLASS, clazz);
        
        // 处理数据列表，将二维码路径转换为图片并补充仓库名称
        for (WmsWarehouseLocation location : pageList) {
            // 获取仓库名称
            if (StringUtils.isNotBlank(location.getWarehouseId())) {
                WmsWarehouse warehouse = wmsWarehouseService.getById(location.getWarehouseId());
                if (warehouse != null) {
                    location.setWarehouseName(warehouse.getWarehouseName());
                }
            }
            
            // 如果有二维码路径，确保其可以作为图片显示
            if (StringUtils.isNotBlank(location.getLocationQrcode())) {
                // 确保路径是完整的文件路径
                String qrcodePath = location.getLocationQrcode();
                if (!qrcodePath.startsWith(uploadPath)) {
                    // 如果不是完整路径，拼接上传路径
                    qrcodePath = uploadPath + File.separator + qrcodePath;
                }
                
                // 检查文件是否存在
                File qrcodeFile = new File(qrcodePath);
                if (!qrcodeFile.exists()) {
                    // 如果文件不存在，清空路径
                    location.setLocationQrcode("");
                }
            }
        }
        
        // 创建自定义导出配置
        List<ExcelExportEntity> entityList = new ArrayList<>();
        
        // 添加需要导出的字段，按指定顺序：库位编号、库位名称、所属仓库、库位二维码、状态、备注
        entityList.add(new ExcelExportEntity("库位编号", "locationCode"));
        entityList.add(new ExcelExportEntity("库位名称", "locationName"));
        entityList.add(new ExcelExportEntity("所属仓库", "warehouseName"));
        
        // 将库位二维码字段设置为图片类型
        ExcelExportEntity locationQrcodeEntity = new ExcelExportEntity("库位二维码", "locationQrcode", 20);
        locationQrcodeEntity.setType(2); // 设置为图片类型
        locationQrcodeEntity.setExportImageType(1); // 导出图片类型为文件
        entityList.add(locationQrcodeEntity);
        
        entityList.add(new ExcelExportEntity("状态", "status"));
        entityList.add(new ExcelExportEntity("备注", "remark"));
        
        // 设置需要导出的实体列表和数据列表（使用直接的字符串而非常量）
        mv.addObject("entityList", entityList);
        mv.addObject("dataList", pageList);
        
        return mv;
    }

    /**
     * 重写page方法，在查询结果中填充仓库名称
     */
    @Override
    public IPage<WmsWarehouseLocation> getByList(Page<WmsWarehouseLocation> page, QueryWrapper<WmsWarehouseLocation> queryWrapper) {
        // 先查询库位列表
        IPage<WmsWarehouseLocation> pageResult = super.page(page, queryWrapper);
        
        // 获取所有查询结果的仓库ID
        List<String> warehouseIds = pageResult.getRecords().stream()
                .map(WmsWarehouseLocation::getWarehouseId)
                .filter(StringUtils::isNotBlank)
                .distinct()
                .collect(Collectors.toList());
        
        if (!warehouseIds.isEmpty()) {
            // 批量查询仓库信息
            List<WmsWarehouse> warehouseList = wmsWarehouseService.listByIds(warehouseIds);
            Map<String, String> warehouseMap = warehouseList.stream()
                    .collect(Collectors.toMap(WmsWarehouse::getId, WmsWarehouse::getWarehouseName, (k1, k2) -> k1));
            Map<String, String> warehouseTypeMap = warehouseList.stream()
                    .collect(Collectors.toMap(WmsWarehouse::getId, WmsWarehouse::getWarehouseType, (k1, k2) -> k1));
            
            // 填充仓库名称
            for (WmsWarehouseLocation location : pageResult.getRecords()) {
                if (StringUtils.isNotBlank(location.getWarehouseId())) {
                    location.setWarehouseName(warehouseMap.get(location.getWarehouseId()));
                    location.setWarehouseType(warehouseTypeMap.get(location.getWarehouseId()));
                }
            }
        }
        
        return pageResult;
    }

    @Override
    public void exportXlsStream(HttpServletResponse response, List<WmsWarehouseLocation> pageList, String title) throws IOException {
        // 实现流式导出逻辑
        // 这里可以使用POI或EasyExcel等工具进行导出
        // 由于实现较为复杂，这里暂不实现
    }
    
    @Override
    public List<WmsWarehouseLocation> queryEmptyLocations(String warehouseId) {
        if (StringUtils.isBlank(warehouseId)) {
            throw new RuntimeException("仓库ID不能为空");
        }
        
        // 查询空闲的库位
        LambdaQueryWrapper<WmsWarehouseLocation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(WmsWarehouseLocation::getWarehouseId, warehouseId);
        queryWrapper.eq(WmsWarehouseLocation::getStatus, "1"); // 1表示空闲
        
        List<WmsWarehouseLocation> emptyLocations = list(queryWrapper);
        
        // 填充仓库名称
        if (emptyLocations != null && !emptyLocations.isEmpty()) {
            WmsWarehouse warehouse = wmsWarehouseService.getById(warehouseId);
                if (warehouse != null) {
                String warehouseName = warehouse.getWarehouseName();
                for (WmsWarehouseLocation location : emptyLocations) {
                    location.setWarehouseName(warehouseName);
                }
            }
        }
        
        return emptyLocations;
    }

    /**
     * 查询可用库位（包括空库位和部分占用的库位）
     */
    @Override
    public List<WmsWarehouseLocation> queryAvailableLocations(String warehouseId) {
        // 查询空库位和部分占用的库位
        LambdaQueryWrapper<WmsWarehouseLocation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(WmsWarehouseLocation::getWarehouseId, warehouseId);
        queryWrapper.in(WmsWarehouseLocation::getStatus, "1", "2"); // 状态为1-空闲或2-部分占用
        
        return this.list(queryWrapper);
    }
    
    /**
     * 获取未完成入库单中已分配的库位信息
     * @return Map<库位ID, 物料编码>
     */
    @Override
    public Map<String, String> getPendingAllocatedLocations() {
        Map<String, String> pendingLocations = new HashMap<>();
        
        try {
            // 使用JDBC直接查询
            Connection conn = null;
            PreparedStatement stmt = null;
            ResultSet rs = null;
            
            try {
                conn = DataSourceUtils.getConnection(dataSource);
                
                // 查询状态为未入库的入库单明细（状态为1-待入库或2-部分入库）
                String sql = "SELECT d.plan_location_id, d.material_code " +
                        "FROM wms_inbound_order_detail d " +
                        "JOIN wms_inbound_order o ON d.inbound_order_id = o.id " +
                        "WHERE o.status IN (1, 2) " +  // 1-待入库, 2-部分入库
                        "AND d.plan_location_id IS NOT NULL";
                
                stmt = conn.prepareStatement(sql);
                rs = stmt.executeQuery();
                
                while (rs.next()) {
                    String locationId = rs.getString("plan_location_id");
                    String materialCode = rs.getString("material_code");
                    if (StringUtils.isNotBlank(locationId)) {
                        pendingLocations.put(locationId, materialCode);
                    }
                }
                
                log.info("查询到{}个未完成入库单中已分配的库位", pendingLocations.size());
            } finally {
                if (rs != null) {
                    try { rs.close(); } catch (SQLException e) { log.error("关闭ResultSet失败", e); }
                }
                if (stmt != null) {
                    try { stmt.close(); } catch (SQLException e) { log.error("关闭PreparedStatement失败", e); }
                }
                if (conn != null) {
                    DataSourceUtils.releaseConnection(conn, dataSource);
                }
            }
        } catch (Exception e) {
            log.error("获取未完成入库单中已分配的库位信息失败", e);
        }
        
        return pendingLocations;
    }

    @Override
    public List<WmsWarehouseLocation> queryPartiallyOccupiedLocations(String warehouseId, String materialCode) {
        if (StringUtils.isBlank(warehouseId)) {
            throw new RuntimeException("仓库ID不能为空");
        }
        
        // 查询未满的库位（状态为2-占用但未满）
        LambdaQueryWrapper<WmsWarehouseLocation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(WmsWarehouseLocation::getWarehouseId, warehouseId);
        //查找库位状态为 空闲1 占用2
        queryWrapper.in(WmsWarehouseLocation::getStatus, Arrays.asList("1", "2"));
        //根据状态倒叙排序
        queryWrapper.orderByDesc(WmsWarehouseLocation::getStatus);
        
        List<WmsWarehouseLocation> partiallyOccupiedLocations = list(queryWrapper);
        
        // 填充仓库名称
        if (partiallyOccupiedLocations != null && !partiallyOccupiedLocations.isEmpty()) {
            WmsWarehouse warehouse = wmsWarehouseService.getById(warehouseId);
            if (warehouse != null) {
                String warehouseName = warehouse.getWarehouseName();
                for (WmsWarehouseLocation location : partiallyOccupiedLocations) {
                    location.setWarehouseName(warehouseName);
                }
            }
        }
        
        return partiallyOccupiedLocations;
    }
} 